package com.csc.dao;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.transaction.Transactional;

import org.springframework.stereotype.Repository;

import com.csc.bean.SystemAccountBean;
import com.csc.domain.SystemAccount;
import com.csc.domain.SystemStatus;
import com.csc.domain.TransactionHistory;

import constants.Constant;

@Repository
public class SystemRequestDAOImpl implements SystemRequestDAO {
	@PersistenceContext
	EntityManager em;

	/**
	 * @author Truong Le Bao
	 */

	// Truong Le Bao
	@Transactional
	public boolean requestResetPassword(String username, String reason) {
		// TODO Auto-generated method stub
		TransactionHistory trh = new TransactionHistory();

		SystemAccount userimpact = em.getReference(SystemAccount.class,
				username);

		TypedQuery<SystemAccount> query = em
				.createQuery(
						"Select p From "
								+ SystemAccount.class.getName()
								+ " p Where p.systemAccountType.typeId = 1 OR p.systemAccountType.typeId = 2 OR p.systemAccountType.typeId = 3",
						SystemAccount.class);
		query.setMaxResults(1);

		// Add Current Date
		Date currentDate = new Date();
		SimpleDateFormat dateFormat = new SimpleDateFormat(
				Constant.SIMPLE_DATE_FORMAT);
		String current = dateFormat.format(currentDate);
		// End - Add Current Date

		SystemAccount useraffected = query.getSingleResult();
		SystemStatus stt = em.getReference(SystemStatus.class, 4);

		// Add New Transaction
		trh.setAccImpact(userimpact);
		trh.setAccAffected(useraffected);
		trh.setDateTransaction(current);
		trh.setActionTransaction(Constant.ACTION_REQUEST_CHANGEPASS);
		trh.setCommand(reason);
		trh.setSystemStatus(stt);

		em.persist(trh);
		// End - Add New Transaction

		// Check Result of Add New Transaction
		String sqlQuery = "SELECT h FROM TransactionHistory h WHERE h.accImpact = :username AND h.dateTransaction = :date AND h.systemStatus = 4 AND h.actionTransaction = 'Reset Password'";
		TypedQuery<TransactionHistory> queryTransac = em.createQuery(sqlQuery,
				TransactionHistory.class);
		queryTransac.setParameter("username", userimpact);
		queryTransac.setParameter("date", current);

		int i = queryTransac.getResultList().size();

		boolean result = i > 0;
		// End - Check Result of Add New Transaction

		return result;
	}

	// Truong Le Bao
	@Override
	public List<TransactionHistory> getListNewTransactionReset() {
		// TODO Auto-generated method stub

		TypedQuery<TransactionHistory> query = em
				.createQuery(
						"Select p From "
								+ TransactionHistory.class.getName()
								+ " p where p.systemStatus = 4 AND p.actionTransaction = 'Reset Password'",
						TransactionHistory.class);

		return query.getResultList();
	}

	// Truong Le Bao - Process Request Update Profile
	@Transactional
	public boolean processRequestUpdateProfile(SystemAccountBean acc,
			String userImpact) {
		// TODO Auto-generated method stub
		try {
			SystemAccount usernameAffect = em.getReference(SystemAccount.class,
					acc.getAccountLoginId());

			// Add New Transaction History of Process Update Profile
			TransactionHistory trh = new TransactionHistory();
			SystemAccount usernameImpact = em.getReference(SystemAccount.class,
					userImpact);
			SystemStatus stt = em.getReference(SystemStatus.class,
					Constant.STATUS_ID_COMPLETE);

			// Add Current Date
			Date currentDate = new Date();
			SimpleDateFormat dateFormat = new SimpleDateFormat(
					Constant.SIMPLE_DATE_FORMAT);
			String current = dateFormat.format(currentDate);
			// End - Add Current Date

			trh.setAccImpact(usernameImpact);
			trh.setAccAffected(usernameAffect);
			trh.setDateTransaction(current);
			trh.setActionTransaction(Constant.ACTION_RESPONSE_DOUPDATEINFO);
			trh.setCommand("Edit Profile for " + acc.getAccountFirstName()
					+ " " + acc.getAccountMidName() + " "
					+ acc.getAccountLastName());
			trh.setSystemStatus(stt);

			em.persist(trh);
			// End - Add New Transaction History of Process Update Profile

			// Process Update Profile

			usernameAffect.setAccountIDCardNumber(acc.getAccountIDCardNumber());
			usernameAffect.setAccountFirstName(acc.getAccountFirstName());
			usernameAffect.setAccountMidName(acc.getAccountMidName());
			usernameAffect.setAccountLastName(acc.getAccountLastName());
			usernameAffect.setAccountPhone1(acc.getAccountPhone1());
			usernameAffect.setAccountPhone2(acc.getAccountPhone2());
			usernameAffect.setAccountEmail1(acc.getAccountEmail1());
			usernameAffect.setAccountEmail2(acc.getAccountEmail2());
			usernameAffect.setAccountAddress1(acc.getAccountAddress1());
			usernameAffect.setAccountAddress2(acc.getAccountAddress2());
			em.persist(usernameAffect);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			return false;
		}
		// End - Process Update Profile

		return true;
	}

	// Truong Le Bao - Process Request Reset Password
	@Transactional
	public boolean processRequestResetPassword(String transactionID, String newPassword, String date,
			String currentUser, String userAffect, int status) {
		// TODO Auto-generated method stub
		try {

			// Update Transaction History of Request Reset Password to complete
			TransactionHistory request = em.getReference(
					TransactionHistory.class, Integer.parseInt(transactionID));
			SystemStatus complete = em.getReference(SystemStatus.class, status);
			request.setSystemStatus(complete);
			em.persist(request);
			// End - Update Transaction History of Reset Password to complete

			// Add New Transaction History of Process Reset Password
			TransactionHistory trh = new TransactionHistory();
			SystemAccount usernameImpact = em.find(SystemAccount.class,
					currentUser);
			SystemAccount usernameAffect = em.find(SystemAccount.class,
					userAffect);

			SystemStatus stt = em.getReference(SystemStatus.class, status);
			// End - Add New Transaction History of Process Reset Password
					
			trh.setAccImpact(usernameImpact);
			trh.setAccAffected(usernameAffect);
			trh.setDateTransaction(date);
			trh.setActionTransaction(Constant.ACTION_REQUEST_CHANGEPASS);
			trh.setCommand("Process Reset Password for " + usernameAffect.getAccountFirstName() + " " + usernameAffect.getAccountMidName() + " " + usernameAffect.getAccountLastName());
			trh.setSystemStatus(stt);

			em.persist(trh);
			// Add New Transaction History of Process Reset Password

			// Process Reset Password
			if (status == 5) {
				try {
					usernameAffect.setAccountPassword(newPassword);
					// usernameAffect.setSystemStatus(new SystemStatus(7,
					// "PreActive"));
					em.persist(usernameAffect);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					return false;
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			return false;
		}
		// End - Process Reset Password

		return true;
	}

	// Truong Le Bao
	@Override
	public TransactionHistory getTransactionByID(int ID) {
		// TODO Auto-generated method stub
		return em.find(TransactionHistory.class, ID);
	}

	// Truong Le Bao
	@Override
	public List<TransactionHistory> searchAdvanceNewRequests(String fullname,
			String username, String role, String from, String to) {
		// TODO Auto-generated method stub

		String sqlQuery = "";

		if (to.equals("")) {
			Date currentDate = new Date();
			SimpleDateFormat dateFormat = new SimpleDateFormat(
					Constant.SIMPLE_DATE_FORMAT);
			to = dateFormat.format(currentDate);
		}

		if (from.equals("")) {
			sqlQuery = "SELECT h FROM TransactionHistory h WHERE h.accImpact.accountLoginId like :username AND h.accImpact.systemAccountType.typeName like :role "
					+ " AND h.systemStatus = 4 AND h.actionTransaction = 'Reset Password' AND h.dateTransaction <= '"
					+ to + "' ORDER BY h.dateTransaction DESC";
		} else {
			sqlQuery = "SELECT h FROM TransactionHistory h WHERE h.accImpact.accountLoginId like :username AND h.accImpact.systemAccountType.typeName like :role "
					+ " AND h.systemStatus = 4 AND h.actionTransaction = 'Reset Password' AND (h.dateTransaction >= '"
					+ from
					+ "' AND h.dateTransaction <= '"
					+ to
					+ "') ORDER BY h.dateTransaction DESC";
		}

		TypedQuery<TransactionHistory> query = em.createQuery(sqlQuery,
				TransactionHistory.class);
		query.setParameter("username", "%" + username + "%");
		query.setParameter("role", "%" + role + "%");

		List<TransactionHistory> listTransaction = query.getResultList();

		for (Iterator<TransactionHistory> iterator = listTransaction.iterator(); iterator
				.hasNext();) {
			SystemAccount acc = iterator.next().getAccImpact();
			String name = acc.getAccountFirstName() + " "
					+ acc.getAccountMidName() + " " + acc.getAccountLastName();

			// Set Conditions to Filters
			boolean checkFullname = name.toLowerCase().contains(
					fullname.trim().toLowerCase());

			// End - Set Conditions to Filters

			if (!checkFullname) {
				iterator.remove();
			}
		}

		return listTransaction;
	}

	@Override
	public boolean isAccountStatusRequestAvailable(String username) {
		// TODO Auto-generated method stub
		String sqlQuery = "SELECT h FROM TransactionHistory h WHERE h.accImpact.accountLoginId = :username"
				+ " AND h.systemStatus = 4 AND h.actionTransaction = 'Reset Password'";
		TypedQuery<TransactionHistory> query = em.createQuery(sqlQuery,
				TransactionHistory.class);
		query.setParameter("username", username);

		if (query.getResultList().size() > 0) {
			return false;
		}

		return true;
	}
}
